package com.yy.young.cms.service.impl;

import com.yy.young.base.util.GlobalConstants;
import com.yy.young.cms.model.DataSource;
import com.yy.young.cms.service.ICmsDataSourceService;
import com.yy.young.cms.service.ICmsVisitService;
import com.yy.young.cms.util.CmsConstants;
import com.yy.young.cms.util.SqlUtil;
import com.yy.young.common.util.DateUtil;
import com.yy.young.common.util.StringUtils;
import com.yy.young.dal.service.IDataAccessService;
import com.yy.young.dal.util.Page;
import com.yy.young.interfaces.model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * cms数据请求服务实现
 * cms客户端服务
 * Created by rookie on 2018/4/9.
 */
@Service("cmsVisitService")
public class CmsVisitServiceImpl implements ICmsVisitService {

    //数据源服务,由cms服务端提供
    @Resource(name="cmsDataSourceService")
    ICmsDataSourceService cmsDataSourceService;

    @Resource(name = "dataAccessService")
    IDataAccessService dataAccessService;//数据层服务

    private static Logger logger = LoggerFactory.getLogger(CmsVisitServiceImpl.class);

    //查询
    @Override
    public List<Map<String, Object>> query(String dataSourceId, Map<String, Object> parameter, Page page) throws Exception {
        if (StringUtils.isNotBlank(dataSourceId)){
            DataSource dataSource = cmsDataSourceService.getDataSource(dataSourceId);
            if (dataSource != null){
                StringBuilder sb = new StringBuilder("SELECT ");
                sb.append(dataSource.getCols());//查询字段
                sb.append(" FROM ");
                sb.append(dataSource.getTableId());//表名
                //处理查询条件
                String where = dataSource.getWhereSql();
                String dq = parameter.get("dq")+"";//搜索栏条件
                //存在搜索栏条件,与数据源配置的条件进行合并
                if(StringUtils.isNotBlank(dq.toString())){
                    if(StringUtils.isNotBlank(where.toString())){//两者都存在,则使用and并操作
                        where = "(" + dq + ")"+CmsConstants.DataSourceConst.AND+"(" + where + ")";
                    }else{//配置为空,则替换
                        where = dq;
                    }
                }
                if(StringUtils.isNotBlank(where)){
                    /*
                     * 处理时间区间,每种区间都有4种情况
                     * 1.使用between关键字的,时间类型的: 使用TO_DATE
                     * 2.使用between关键字的,字符类型的: 直接between时间区间
                     * 3.使用其他关键字的,时间类型的: 用TO_DATE去替换
                     * 4.使用其他关键字的,字符类型的: 直接用对应时间字符串替换
                     */
                    String today = DateUtil.getCurrentDay();//当天
                    String tomorrow = DateUtil.afterNDay(new Date(),1,"yyyy-MM-dd");//明天
                    String month = DateUtil.getCurrentDay().substring(0, 7);//年月
                    int year = DateUtil.getCurrentYear();//今年
                    //处理当天
                    where = where.replaceAll(CmsConstants.DataSourceConst.BETWEEN_D_TODAY, " BETWEEN "+SqlUtil.formatTimeStr(today+" 00:00:00", dataAccessService.getDBType())+" AND "+SqlUtil.formatTimeStr(today + " 23:59:59", dataAccessService.getDBType()));
                    where = where.replaceAll(CmsConstants.DataSourceConst.BETWEEN_S_TODAY, " BETWEEN '"+today+"'" + " AND "+"'"+tomorrow+"'");
                    where = where.replaceAll(CmsConstants.DataSourceConst.D_TODAY, SqlUtil.formatDateStr(today, dataAccessService.getDBType()));//将日期字符串格式化为sql日期表达式
                    where = where.replaceAll(CmsConstants.DataSourceConst.S_TODAY, "'"+today+"'");
                    //处理当月
                    where = where.replaceAll(CmsConstants.DataSourceConst.BETWEEN_D_MONTH, " BETWEEN "+SqlUtil.formatTimeStr(month + "-01 00:00:00", dataAccessService.getDBType())+" AND "+SqlUtil.formatTimeStr(DateUtil.getCurrentMonthMaxDay() + " 23:59:59", dataAccessService.getDBType()));
                    where = where.replaceAll(CmsConstants.DataSourceConst.BETWEEN_S_MONTH, " BETWEEN '"+month+"-01 00:00:00"+"' AND '"+DateUtil.getCurrentMonthMaxDay()+" 23:59:59'");
                    where = where.replaceAll(CmsConstants.DataSourceConst.D_MONTH, SqlUtil.formatYearMonthStr(month, dataAccessService.getDBType()));
                    where = where.replaceAll(CmsConstants.DataSourceConst.S_MONTH,"'"+month+"'");
                    //去年
                    where = where.replaceAll(CmsConstants.DataSourceConst.BETWEEN_D_LAST_YEAR, " BETWEEN "+SqlUtil.formatTimeStr((year - 1) + "-01-01 00:00:00", dataAccessService.getDBType())+" AND "+SqlUtil.formatTimeStr((year - 1) + "-12-31 23:59:59", dataAccessService.getDBType()));
                    where = where.replaceAll(CmsConstants.DataSourceConst.BETWEEN_S_LAST_YEAR, " BETWEEN '"+(year-1)+"-01-01 00:00:00"+"' AND '"+(year-1)+"-12-31 23:59:59'");
                    where = where.replaceAll(CmsConstants.DataSourceConst.D_LAST_YEAR, SqlUtil.formatYearStr(year-1+"", dataAccessService.getDBType()));
                    where = where.replaceAll(CmsConstants.DataSourceConst.S_LAST_YEAR, "'"+(year-1)+"'");
                    //今年
                    where = where.replaceAll(CmsConstants.DataSourceConst.BETWEEN_D_THIS_YEAR, " BETWEEN "+SqlUtil.formatTimeStr(year + "-01-01 00:00:00", dataAccessService.getDBType())+" AND "+SqlUtil.formatTimeStr(year + "-12-31 23:59:59", dataAccessService.getDBType()));
                    where = where.replaceAll(CmsConstants.DataSourceConst.BETWEEN_S_THIS_YEAR, " BETWEEN '"+year+"-01-01 00:00:00"+"' AND '"+year+"-12-31 23:59:59'");
                    where = where.replaceAll(CmsConstants.DataSourceConst.D_THIS_YEAR, SqlUtil.formatYearStr(year+"", dataAccessService.getDBType()));
                    where = where.replaceAll(CmsConstants.DataSourceConst.S_THIS_YEAR, "'"+(year)+"'");
                    //明年
                    where = where.replaceAll(CmsConstants.DataSourceConst.BETWEEN_D_NEXT_YEAR, " BETWEEN "+SqlUtil.formatTimeStr((year + 1) + "-01-01 00:00:00", dataAccessService.getDBType())+" AND "+SqlUtil.formatTimeStr((year + 1) + "-12-31 23:59:59", dataAccessService.getDBType()));
                    where = where.replaceAll(CmsConstants.DataSourceConst.BETWEEN_S_NEXT_YEAR, " BETWEEN '"+(year+1)+"-01-01 00:00:00"+"' AND '"+(year+1)+"-12-31 23:59:59'");
                    where = where.replaceAll(CmsConstants.DataSourceConst.D_NEXT_YEAR, " " + SqlUtil.formatYearStr(year+1+"", dataAccessService.getDBType()));
                    where = where.replaceAll(CmsConstants.DataSourceConst.S_NEXT_YEAR, "'"+(year+1)+"'");

                    /*
                     * 处理关键字
                     * 在处理完上面的多关键字组合的情况后,对剩余的关键字直接进行替换
                     */
                    where = where.replaceAll(CmsConstants.DataSourceConst.AND, " AND ");
                    where = where.replaceAll(CmsConstants.DataSourceConst.OR, " OR ");
                    where = where.replaceAll(CmsConstants.DataSourceConst.EQUAL, " = ");
                    where = where.replaceAll(CmsConstants.DataSourceConst.NOT_EQUAL, " != ");
                    where = where.replaceAll(CmsConstants.DataSourceConst.GT, " > ");
                    where = where.replaceAll(CmsConstants.DataSourceConst.LT, " < ");
                    where = where.replaceAll(CmsConstants.DataSourceConst.LIKE, " LIKE ");
                    where = where.replaceAll(CmsConstants.DataSourceConst.IN, " IN ");
                    where = where.replaceAll(CmsConstants.DataSourceConst.BETWEEN, " BETWEEN ");

                    /*
                     * 替换当前用户属性常量
                     */
                    User user = (User)parameter.get(GlobalConstants.SESSION.KEY_LOGINUSER);
                    if(user != null){
                        where = where.replaceAll(CmsConstants.DataSourceConst.USER_ID, " '" + user.getId() + "' ");
                        where = where.replaceAll(CmsConstants.DataSourceConst.USER_NAME, " '" + user.getName() + "' ");
                        where = where.replaceAll(CmsConstants.DataSourceConst.USER_ROLE_ID, " '" + user.getRoleId() + "' ");
                        where = where.replaceAll(CmsConstants.DataSourceConst.USER_COMPANY_ID, " '" + user.getCompanyId() + "' ");
                        where = where.replaceAll(CmsConstants.DataSourceConst.USER_COMPANY_NAME, " '" + user.getCompanyName() + "' ");
                    }
                    sb.append(" WHERE ");
                    sb.append(where);
                }
                //排序sql
                if (StringUtils.isNotBlank(dataSource.getOrderSql())){
                    sb.append(" ORDER BY ").append(dataSource.getOrderSql());
                }
                //执行查询sql
                logger.debug("[CMS数据源解析为SQL] 数据源({})解析后为: {}", dataSourceId, sb);
                if(page != null){
                    return dataAccessService.getList(CmsConstants.MAPPER.CMS_VISIT + ".query", sb.toString(), page);
                }else{
                    return dataAccessService.getList(CmsConstants.MAPPER.CMS_VISIT + ".query", sb.toString());
                }
            }else{
                logger.warn("[CMS数据源检索] 查找不到对应的数据源[{}]!", dataSourceId);
            }
        }else{
            logger.warn("[CMS数据源检索] 数据源ID无效!");
        }
        return null;
    }
}
